package com.example.service;

import org.quartz.Job;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class JobClassService {

    public List<Map<String, String>> getAllJobClasses() {
        List<Class<? extends Job>> jobClasses = scanJobClasses();
        return jobClasses.stream()
                .map(jobClass -> {
                    Map<String, String> jobMap = new HashMap<>();
                    jobMap.put("className", jobClass.getName());
                    jobMap.put("simpleName", jobClass.getSimpleName());
                    jobMap.put("description", getJobDescription(jobClass));
                    return jobMap;
                })
                .collect(Collectors.toList());
    }

    private List<Class<? extends Job>> scanJobClasses() {
        List<Class<? extends Job>> jobClasses = new ArrayList<>();
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AssignableTypeFilter(Job.class));

        String basePackage = "com.example.job";
        for (BeanDefinition bd : scanner.findCandidateComponents(basePackage)) {
            try {
                Class<?> jobClass = Class.forName(bd.getBeanClassName());
                if (Job.class.isAssignableFrom(jobClass)) {
                    jobClasses.add((Class<? extends Job>) jobClass);
                }
            } catch (ClassNotFoundException e) {
                // Skip if class cannot be loaded
            }
        }
        return jobClasses;
    }

    private String getJobDescription(Class<? extends Job> jobClass) {
        try {
            return jobClass.getSimpleName();
        } catch (Exception e) {
            return jobClass.getName();
        }
    }
}